#include <chainsaw.h>
#include "SimpleTable.h"

template <typename... Args>
void print_error(Args &&...args)
{
    chainsaw::print_class_error("SimpleTable", std::forward<Args>(args)...);
}

SimpleTable::SimpleTable(int rows) : m_rows(rows)
{
    m_ele_size.resize(rows, 1);

    m_limit.ele_max_limit = 20;
    m_limit.ele_min_limit = 1;
    m_limit.line_max_limit = 200;
}

//
void print_table_separator(std::deque<int> const &data, char symbol)
{
    chain::info_nowrap("+");
    for (int i = 0; i < data.size(); ++i)
    {
        for (int j = 0; j < data[i]; ++j)
        {
            chain::raw(symbol);
        }
        chain::raw("+");
    }
    chain::raw_endl();
}

void SimpleTable::set_tittle(std::vector<std::string> data)
{
    if (data.size() > m_ele_size.size())
    {
        print_error("tittle-ele-size is more than table-ele-size");
        return;
    }

    if (data.size() < m_ele_size.size())
    {
        if (!m_flags.is_quiet)
        {
            chain::warn("tittle-ele-size is less than table-ele-size");
        }
    }

    m_flags.has_tittle = true;

    For(data.size())
    {
        auto size = data[ii].size();
        if (m_ele_size[ii] < size)
        {
            m_ele_size[ii] = size;
        }
    }

    For(m_ele_size.size() - data.size())
    {
        data.push_back("");
    }

    m_data.push_back(data);
}

void SimpleTable::add_line(std::vector<std::string> const &data)
{
    m_data.push_back(data);

    int n = std::min(static_cast<int>(data.size()), m_rows);

    For(n)
    {
        auto size = data[ii].size();

        if (m_ele_size[ii] < size)
        {
            m_ele_size[ii] = size;
        }
    }
}

void SimpleTable::set_quiet(bool enable)
{
    m_flags.is_quiet = enable;
}

void print_table_data(std::vector<std::string> const &data, std::deque<int> const &ele_size)
{
    chain::info_nowrap("|");

    For(data.size())
    {
        auto t = data[ii];
        int limit = ele_size[ii];
        int n = static_cast<int>(t.size());

        chain::raw(t);
        For(limit - n)
        {
            chain::raw(" ");
        }
        chain::raw("|");
    }
    chain::raw_endl();
}

void SimpleTable::print() const
{
    if (m_data.empty())
    {
        cns::info("+-------------+");
        cns::info("| It's empty. |");
        cns::info("+-------------+");
        return;
    }

    // top-line
    if(m_flags.has_tittle)
        print_table_separator(m_ele_size, '=');
    else
        print_table_separator(m_ele_size, '-');

    int i = 0;
    if(m_flags.has_tittle)
    {
        print_table_data(m_data[i++],m_ele_size);
        print_table_separator(m_ele_size, '=');
    }

    // table
    for (; i < m_data.size(); ++i)
    {
        print_table_data(m_data[i], m_ele_size);

        //
        print_table_separator(m_ele_size, '-');
    }
}
